package com.competitions.videoedithelper.utils;

import org.jaudiotagger.audio.AudioFileIO;
import org.jaudiotagger.audio.mp3.MP3AudioHeader;
import org.jaudiotagger.audio.mp3.MP3File;
import org.springframework.web.multipart.MultipartFile;
import ws.schild.jave.MultimediaInfo;
import ws.schild.jave.MultimediaObject;

import java.io.DataOutputStream;
import java.io.File;
import java.util.UUID;

/**
 * @author 盛旭雯
 */
public class AudioUtil {
    //private static final String FFMPEG_PATH="C:\\video_edit_helper\\lib\\ffmpeg\\bin\\ffmpeg.exe";
    private static final String FFMPEG_PATH="/usr/bin/ffmpeg";
    /**
     * 获取音频总时间
     * @param audio  音频文件
     * @return long
     */
    public static long getAudioTime(File audio){
        long duration=0;
        try{
            modifyPermission();//本地测试不需要
            MultimediaObject multimediaObject = new MultimediaObject(audio);
            MultimediaInfo info = multimediaObject.getInfo();
            duration = info.getDuration()/1000;
        }catch (Exception e){
            e.printStackTrace();
            System.out.println("获取时长失败");
        }
        System.out.println(duration);
        return duration;
    }

    /**
     * 获取修改文件权限
     */
    private static void modifyPermission(){
        String[] commands = new String[] { "chmod 777 /tmp/jave/ffmpeg-amd64-2.4.6-SNAPSHOT" };
        Process process = null;
        DataOutputStream dataOutputStream = null;
        try {
            process = Runtime.getRuntime().exec("su");
            dataOutputStream = new DataOutputStream(process.getOutputStream());
            int length = commands.length;
            for (String command : commands) {
                dataOutputStream.writeBytes(command + "\n");
            }
            dataOutputStream.writeBytes("exit\n");
            dataOutputStream.flush();
            process.waitFor();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (dataOutputStream != null) {
                    dataOutputStream.close();
                }
                assert process != null;
                process.destroy();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 获取mp3总时间
     * @param mp3File  音频文件
     * @return int
     */
    public static int getMp3Length(File mp3File) {
        try {
            MP3File f = (MP3File) AudioFileIO.read(mp3File);
            MP3AudioHeader audioHeader = (MP3AudioHeader)f.getAudioHeader();
            return audioHeader.getTrackLength();
        } catch(Exception e) {
            System.out.println("获取时长失败");
            return -1;
        }
    }

    /**
     * 音频格式转换
     * @param audioPath  音频文件路径
     * @return String
     */
    public static String wavToMp3(String audioPath){
        String outputPath=audioPath.substring(0,audioPath.lastIndexOf("."))+".mp3";
        String command=FFMPEG_PATH+" -i "+audioPath+" -ar 16000 -f mp3 "+outputPath;
        System.out.println(command);
        try {
            Process process = Runtime.getRuntime().exec(command);
            process.waitFor();
        }catch (Exception e){
            e.printStackTrace();
        }
        File file=new File(outputPath);
        if (file.exists()){
            return outputPath;
        }
        return null;
    }

    /**
     * 截取两头音频
     * @param filePath  音频文件路径
     * @param duration 音频时长
     * @param begin 开始时间
     * @param end 结束时间
     * @param pathDir 音频保存的相对路径
     * @return String[]
     */
    public static String[] cutAudio(String filePath,int duration, String begin, String end,String pathDir){
        String path1=pathDir+UUID.randomUUID()+".mp3";
        String command1=FFMPEG_PATH+" -ss 00:00:00 -t "+begin+" -i "+filePath+" "+path1;
        System.out.println(command1);

        int len12=UploadFileUtil.getTimelen(end);
        String len3=UploadFileUtil.getTime(duration-len12);
        String path3=pathDir+UUID.randomUUID()+".mp3";
        String command2=FFMPEG_PATH+" -ss "+end+" -t "+len3+" -i "+filePath+" "+path3;
        System.out.println(command2);

        try {
            if(!"00:00:00".equals(begin)){
                Process process1 = Runtime.getRuntime().exec(command1);
                process1.waitFor();
            }else {
                path1=null;
            }
            Process process2 = Runtime.getRuntime().exec(command2);
            process2.waitFor();
        }catch (Exception e){
            e.printStackTrace();
        }

        File file1=null;
        if(path1!=null){
            file1=new File(path1);
        }
        File file3=new File(path3);
        if (file1!=null){
            if (!file1.exists()){
                System.out.println("第一段音频截取失败");
            }else if(!file3.exists()){
                System.out.println("第三段音频截取失败");
            }else {
                return new String[]{path1, path3};
            }
        }else {
            if(!file3.exists()){
                System.out.println("第三段音频截取失败");
            }else {
                return new String[]{path1, path3};
            }
        }
        File[] files={file1,file3};
        FileUtil.deleteFiles(files);
        return null;
    }

    /**
     * 截取中间音频
     * @param filePath  音频文件路径
     * @param begin 开始时间
     * @param end 结束时间
     * @param pathDir 音频保存的相对路径
     * @return String
     */
    public static String cutAudio2(String filePath, String begin, String end,String pathDir){
        String path2=pathDir+UUID.randomUUID()+".mp3";
        int len1=UploadFileUtil.getTimelen(begin);
        int len2=UploadFileUtil.getTimelen(end);
        String len=UploadFileUtil.getTime(len2-len1);
        String command=FFMPEG_PATH+" -ss "+begin+" -t "+len+" -i "+filePath+" "+path2;
        System.out.println(command);

        try {
            Process process = Runtime.getRuntime().exec(command);
            process.waitFor();
        }catch (Exception e){
            e.printStackTrace();
        }

        File file=new File(path2);
        if (!file.exists()){
            System.out.println("音频截取失败");
        } else {
            return path2;
        }
        return null;
    }

    /**
     * 拼接音频
     * @param path1  音频片段路径1
     * @param path2 音频片段路径2
     * @param path3 音频片段路径3
     * @param pathDir 音频保存的相对路径
     * @return String
     */
    public static String pieceAudio(String path1,String path2,String path3,String pathDir){
        String path4=pathDir+UUID.randomUUID()+".mp3";
        String command3;
        if(path1==null){
            command3=FFMPEG_PATH+" -i \"concat:"+path2+"|"+path3+"\" -acodec copy "+path4;
        }else {
            command3=FFMPEG_PATH+" -i \"concat:"+path1+"|"+path2+"|"+path3+"\" -acodec copy "+path4;
        }
        System.out.println(command3);
        try {
            //Process process3=Runtime.getRuntime().exec(command3);
            Process process3 = Runtime.getRuntime().exec(new String[]{"sh","-c",command3});
            StreamUtil.dealStream(process3);
            process3.waitFor();
        }catch (Exception e){
            e.printStackTrace();
        }
        File file4=new File(path4);
        if(!file4.exists()){
            System.out.println("拼接音频失败");
        }else {
            return path4;
        }
        return null;
    }

    /**
     * 转存音频
     * @param part  替换音频
     * @param partPath 音频保存的路径
     * @return String
     */
    public static String transAudio(MultipartFile part, String partPath){
        File file2=new File(partPath);
        try {
            part.transferTo(file2);
        } catch (Exception e) {
            e.printStackTrace();
        }
        if(!file2.exists()){
            System.out.println("转存音频失败");
        }else {
            return partPath;
        }
        return null;
    }

    public static boolean combineVideo(String initVideoPath,String audioPath,String newVideoPath){
        String command=FFMPEG_PATH+" -i "+initVideoPath+" -i "+audioPath+" -c:v copy -c:a aac -strict experimental -map 0:v:0 -map 1:a:0 -y "+newVideoPath;
        System.out.println(command);

        try {
            Process process = Runtime.getRuntime().exec(command);
            StreamUtil.dealStream(process);
            process.waitFor();
        }catch (Exception e){
            e.printStackTrace();
        }

        File file=new File(newVideoPath);
        if (!file.exists()){
            System.out.println("合成视频失败");
        } else {
            return true;
        }
        return false;
    }
}
